//
//  PrimittivesScene.m
//  StudySceneKit
//
//  Created by Moyun on 2017/8/30.
//  Copyright © 2017年 Cmall. All rights reserved.
//

#import "PrimittivesScene.h"
#import <sys/utsname.h>

@interface PrimittivesScene ()<SCNNodeRendererDelegate>{
    SCNNode *_lightSuperNode;
    BOOL _light;
}

@end

@implementation PrimittivesScene


- (void)changeSeceneLightEnvironment:(BOOL)light{
    if (light == _light) {
        return;
    }
    _light = light;
//    if (light) {
//        [self setupLightEnvironment];
//    }else{
//        [self setupDarkEnvironment];
//    }
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.colors = @[@"M001.png",@"M002.png",@"M003.png",@"M007.png",@"M009.png",@"M013.png",@"M024.png",@"M032.png",@"M033.png",@"M034.png",@"M035.png",@"M036.png",@"M037.png",@"M038.png",@"M0039.png",@"M040.png",@"M041.png",@"M042.png",@"M043.png",@"M044.png",@"M045.png",@"M046.png",@"M047.png"];
        
        _lightSuperNode = [SCNNode node];
        [self commonInit];
    }
    return self;
}

- (void)commonInit
{
    [self.rootNode addChildNode:_lightSuperNode];
    
    // 设置环境
//    [self changeSeceneLightEnvironment:true];
    
    // 添加地板和墙
//    [self setupFloorAndWall];
    
    // 加载模型
    [self loadClothes];
    // 添加约束
    [self setupConstraint];
    
    // 添加自转
    [self setupRound];
}

- (void)setupLightEnvironment{
    
    for (SCNNode *node in _lightSuperNode.childNodes) {
        [node removeFromParentNode];
    }
    
    // 添加dire灯
    SCNNode *direLightNode = [SCNNode node];
    direLightNode.position = SCNVector3Make(-200, 50, -20);
    direLightNode.eulerAngles = SCNVector3Make(0, 51.26/180.0*M_PI, 0);
    direLightNode.light = [SCNLight light];
    direLightNode.light.color = [PrimittivesScene colorWithHex:0x999999 alpha:0.876];
    direLightNode.light.type = SCNLightTypeDirectional;
    if ([self isHighEndDevice])
        direLightNode.castsShadow = true;
    direLightNode.light.zFar = 1500;
    direLightNode.light.zNear = 200;
    direLightNode.light.shadowBias = -0.005;
    direLightNode.light.shadowMapSize = CGSizeMake(2048, 2048);
    direLightNode.light.shadowMode = false;
    [_lightSuperNode addChildNode:direLightNode];
    
    // 添加omni灯
    SCNNode *omniLightNode = [SCNNode node];
    omniLightNode.position = SCNVector3Make(200, 0, 0);
    omniLightNode.light = [SCNLight light];
    omniLightNode.light.color = [PrimittivesScene colorWithHex:0x777777 alpha:0.876];
    omniLightNode.light.type = SCNLightTypeOmni;
    [_lightSuperNode addChildNode:omniLightNode];
    
    // 添加灯ambi灯
    SCNNode *ambiLightNode = [SCNNode node];
    ambiLightNode.position = SCNVector3Make(0, 0, 0);
    ambiLightNode.light = [SCNLight light];
    ambiLightNode.light.color = [PrimittivesScene colorWithHex:0xCDCDCD alpha:1.0];
    ambiLightNode.light.type = SCNLightTypeAmbient;
    [_lightSuperNode addChildNode:ambiLightNode];
}

- (void)setupDarkEnvironment{
    
    for (SCNNode *node in _lightSuperNode.childNodes) {
        [node removeFromParentNode];
    }
    
    // 添加Dire灯
    SCNNode *oneDireNode = [SCNNode node];
    oneDireNode.position = SCNVector3Make(100, 100, 100);
    oneDireNode.eulerAngles = SCNVector3Make(-45/180*M_PI, 45/180*M_PI, 0);
    oneDireNode.light = [SCNLight light];
    oneDireNode.light.color = [UIColor whiteColor];
    oneDireNode.light.type = SCNLightTypeDirectional;
    [_lightSuperNode addChildNode:oneDireNode];
    
    // 添加Dire灯
    SCNNode *twoDireNode = [SCNNode node];
    twoDireNode.position = SCNVector3Make(-100, 100, 100);
    twoDireNode.eulerAngles = SCNVector3Make(-45/180*M_PI, -45/180*M_PI, 0);
    twoDireNode.light = [SCNLight light];
    twoDireNode.light.color = [UIColor whiteColor];
    twoDireNode.light.type = SCNLightTypeDirectional;
    [_lightSuperNode addChildNode:twoDireNode];
    
    // 添加Dire灯
    SCNNode *threeDireNode = [SCNNode node];
    threeDireNode.position = SCNVector3Make(0, 100, -100);
    threeDireNode.eulerAngles = SCNVector3Make(0, M_PI, 0);
    threeDireNode.light = [SCNLight light];
    threeDireNode.light.color = [UIColor whiteColor];
    threeDireNode.light.type = SCNLightTypeDirectional;
    [_lightSuperNode addChildNode:threeDireNode];
    
    // 添加灯ambi灯
    SCNNode *ambiLightNode = [SCNNode node];
    ambiLightNode.position = SCNVector3Make(0, 0, 0);
    ambiLightNode.light = [SCNLight light];
    ambiLightNode.light.color = [UIColor whiteColor];
    ambiLightNode.light.type = SCNLightTypeAmbient;
    [_lightSuperNode addChildNode:ambiLightNode];
}

- (void)setupFloorAndWall{
    //floor
    SCNNode*floor = [SCNNode node];
    floor.position = SCNVector3Make(0, -500, 0);
    floor.geometry = [SCNFloor floor];
    floor.geometry.firstMaterial.diffuse.contents = @"wood.png";
    floor.geometry.firstMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(2, 2, 1); //scale the wood texture
    floor.geometry.firstMaterial.locksAmbientWithDiffuse = YES;
    if ([self isHighEndDevice])
        ((SCNFloor*)floor.geometry).reflectionFalloffEnd = 10;
    
    SCNPhysicsBody *staticBody = [SCNPhysicsBody staticBody];
    floor.physicsBody = staticBody;
        [self.rootNode addChildNode:floor];
    
    // add walls
    SCNNode *wall = [SCNNode nodeWithGeometry:[SCNBox boxWithWidth:4000 height:1000 length:4 chamferRadius:0]];
    wall.geometry.firstMaterial.diffuse.contents = @"wall.jpg";
    wall.geometry.firstMaterial.diffuse.contentsTransform = SCNMatrix4Mult(SCNMatrix4MakeScale(24, 2, 1), SCNMatrix4MakeTranslation(0, 1, 0));
    wall.geometry.firstMaterial.diffuse.wrapS = SCNWrapModeRepeat;
    wall.geometry.firstMaterial.diffuse.wrapT = SCNWrapModeMirror;
    wall.geometry.firstMaterial.doubleSided = NO;
    wall.castsShadow = NO;
    wall.geometry.firstMaterial.locksAmbientWithDiffuse = YES;
    
    wall.position = SCNVector3Make(0, 0, -2000);
    wall.physicsBody = [SCNPhysicsBody staticBody];
//        [self.rootNode addChildNode:wall];
    
    wall = [wall clone];
    wall.position = SCNVector3Make(-2000, 0, 0);
    wall.rotation = SCNVector4Make(0, 1, 0, M_PI_2);
//        [self.rootNode addChildNode:wall];
    
    wall = [wall clone];
    wall.position = SCNVector3Make(2000, 0, 0);
    wall.rotation = SCNVector4Make(0, 1, 0, -M_PI_2);
//        [self.rootNode addChildNode:wall];
    
    SCNNode *backWall = [SCNNode nodeWithGeometry:[SCNPlane planeWithWidth:4000 height:1000]];
    backWall.geometry.firstMaterial = wall.geometry.firstMaterial;
    backWall.position = SCNVector3Make(0, 0, 2000);
    backWall.rotation = SCNVector4Make(0, 1, 0, M_PI);
    backWall.castsShadow = NO;
    backWall.physicsBody = [SCNPhysicsBody staticBody];
//        [self.rootNode addChildNode:backWall];
}

- (void)loadClothes{
    SCNScene *scene = [SCNScene sceneNamed:@"Tee001_3D"];
//    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Tee001_3D" ofType:@"FBX"];
//
//    NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
//    
//    NSError *error = nil;
//    SCNScene *scene = [SCNScene sceneWithURL:fileUrl options:nil error:&error];
//    if (error) {
//        NSLog(@"==error:%@",error);
//        return;
//    }
//    NSURL *documentDirectoryUrl = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:nil];
//    documentDirectoryUrl = [documentDirectoryUrl URLByAppendingPathComponent:@"Test001_3D.scnassets/Sweater001_3D.DAE"];
//    SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithURL:documentDirectoryUrl options:nil];
    
//    NSData *sceneData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://imgdevex.cmall.com/Test002_3D.dae"]];
//    if (sceneData == nil) {
//        return;
//    }
//    
//    SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithData:sceneData options:nil];
//
    
//    SCNScene *scene  = [sceneSource sceneWithOptions:nil statusHandler:^(float totalProgress, SCNSceneSourceStatus status, NSError * _Nullable error, BOOL * _Nonnull stop) {
//        
//        NSLog(@"==progress:%f==status:%ld==error:%@",totalProgress,(long)status,error);
//    }];
//    SCNScene *scene = [SCNScene sceneWithURL:documentDirectoryUrl options:nil error:nil];
    if (scene) {
        [self loadSecne:scene];
    }
}

- (void)loadSecne:(SCNScene*)scene{
    NSLog(@"==startLoad==");
    for (SCNNode *chidNode in scene.rootNode.childNodes) {
        NSLog(@"==node name:%@",chidNode.name);
        
        SCNGeometry *geometry = chidNode.geometry;
        NSArray *array = geometry.materials;
        for (SCNMaterial *material in array) {
            @autoreleasepool {
                NSLog(@"==material:%@",material.name);
                material.doubleSided = true;
            }
        }
        [self.rootNode addChildNode:chidNode];
    }
    [self reloadSeceneWithColorName:self.colors.firstObject];
}

- (void)reloadSeceneWithColorName:(NSString*)colorName{
    for (SCNNode *chidNode in self.rootNode.childNodes) {
        SCNGeometry *geometry = chidNode.geometry;
        NSArray *array = geometry.materials;
        for (SCNMaterial *material in array) {
            @autoreleasepool {
                NSLog(@"==material:%@",material.name);
//                material.multiply.contents = colorName;
            }
        }
    }
}

- (void)setupConstraint{
//    SCNLookAtConstraint *lookCons = [SCNLookAtConstraint lookAtConstraintWithTarget:_clothNode];
//    [lookCons setGimbalLockEnabled:true];
//    self.rootNode.constraints = @[lookCons];
}

- (void)setupRound{
//    SCNAction *repetAction = [SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:5]];
//    [self.rootNode runAction:repetAction];
}

#pragma mark -

- (BOOL)isHighEndDevice
{
    //return YES for iPhone 5s and iPad air, NO otherwise
    if ([[self deviceName] hasPrefix:@"iPad4"]
        || [[self deviceName] hasPrefix:@"iPhone6"]) {
        return YES;
    }
    
    return NO;
}

- (NSString *)deviceName
{
    static NSString *deviceName = nil;
    
    if (deviceName == nil) {
        struct utsname systemInfo;
        uname(&systemInfo);
        
        deviceName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    }
    return deviceName;
}

+ (UIColor *)colorWithHex:(long)hexColor alpha:(float)opacity
{
    float red = ((float)((hexColor & 0xFF0000) >> 16))/255.0;
    float green = ((float)((hexColor & 0xFF00) >> 8))/255.0;
    float blue = ((float)(hexColor & 0xFF))/255.0;
    return [UIColor colorWithRed:red green:green blue:blue alpha:opacity];
}

@end
